//! Simulating files one step at a time
use std::fmt::{self, Display};

///Reprisents a "file",
/// which probably lives on file system.
#[derive(Debug, PartialEq)]
enum FileState{
    Open,
    Closed,
}


#[derive(Debug)]
pub struct File {
    name: String,
    data: Vec<u8>,
    state: FileState,
}

impl File{
    /// Creates a new, empty `File`. ///
    /// # Examples ///
    /// ```
    /// let f = File::new("f1.txt");
    /// ```
    pub fn new(name: &str) -> File{
        File{
            name: String::from(name),
            data: Vec::new(),
            state: FileState::Closed,
        }
    }

    pub fn len(&self) -> usize{
        self.data.len()
    }

    pub fn name(&self) -> String{
        self.name.clone()
    }
}

impl fmt::Display for FileState {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
        match *self {
            FileState::Open => write!(f, "OPEN"),
            FileState::Closed => write!(f, "CLOSED"),
        }
    }
}

impl Display for File{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
        write!(f, "<{} ({})>",self.name, self.state)
    }
}

pub fn open(mut f: File) -> Result<File, String> {
    f.state = FileState::Open;
    Ok(f)
}

pub fn close(mut f: File) -> Result<File, String> {
    f.state = FileState::Closed;
    Ok(f)
}